/**
 * 智能告警系统
 * EndoSight-UC 医疗AI系统
 *
 * 基于健康检查和指标的智能告警系统
 */

import winston from 'winston';
import { performDeepHealthCheck } from './healthChecker.js';
import { getMetricsSummary } from './metrics.js';

// 配置日志记录器
const logger = winston.createLogger({
  level: 'info',
  format: winston.format.combine(
    winston.format.timestamp(),
    winston.format.json()
  ),
  transports: [
    new winston.transports.Console({
      format: winston.format.simple()
    }),
    new winston.transports.File({
      filename: 'logs/alerts.log'
    })
  ]
});

// 告警级别
export const AlertSeverity = {
  INFO: 'info',
  WARNING: 'warning',
  CRITICAL: 'critical',
  EMERGENCY: 'emergency'
};

// 告警类型
export const AlertType = {
  SYSTEM_HEALTH: 'system_health',
  PERFORMANCE: 'performance',
  SECURITY: 'security',
  RESOURCE: 'resource',
  SERVICE_AVAILABILITY: 'service_availability',
  BUSINESS_METRIC: 'business_metric'
};

// 告警状态
export const AlertStatus = {
  ACTIVE: 'active',
  ACKNOWLEDGED: 'acknowledged',
  RESOLVED: 'resolved',
  SUPPRESSED: 'suppressed'
};

// 告警配置
const ALERT_THRESHOLDS = {
  // 性能阈值
  responseTime: {
    warning: 1000,    // 1秒
    critical: 3000    // 3秒
  },
  errorRate: {
    warning: 0.05,    // 5%
    critical: 0.15    // 15%
  },
  memoryUsage: {
    warning: 0.80,    // 80%
    critical: 0.95    // 95%
  },
  cpuUsage: {
    warning: 0.70,    // 70%
    critical: 0.90    // 90%
  },
  diskUsage: {
    warning: 0.80,    // 80%
    critical: 0.95    // 95%
  },
  // 业务指标阈值
  aiInferenceFailureRate: {
    warning: 0.10,    // 10%
    critical: 0.25    // 25%
  },
  databaseConnectionFailureRate: {
    warning: 0.05,    // 5%
    critical: 0.15    // 15%
  }
};

// 告警抑制规则（避免告警风暴）
const SUPPRESSION_RULES = {
  // 同类型告警抑制时间（毫秒）
  sameAlertSuppression: 300000,        // 5分钟
  // 依赖告警抑制（如果根因告警已存在，抑制相关告警）
  dependencySuppression: true,
  // 告警风暴检测
  alertStormThreshold: 10,             // 10分钟内超过10个告警
  alertStormWindow: 600000             // 10分钟
};

// 活跃告警存储
const activeAlerts = new Map();
const alertHistory = [];
const suppressionRules = new Map();

/**
 * 告警类
 */
class Alert {
  constructor(type, severity, title, message, details = {}) {
    this.id = this.generateAlertId();
    this.type = type;
    this.severity = severity;
    this.title = title;
    this.message = message;
    this.details = details;
    this.status = AlertStatus.ACTIVE;
    this.timestamp = new Date().toISOString();
    this.lastUpdated = new Date().toISOString();
    this.acknowledgedBy = null;
    this.acknowledgedAt = null;
    this.resolvedAt = null;
    this.suppressionCount = 0;
    this.correlationId = details.correlationId || null;
  }

  generateAlertId() {
    return `alert_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
  }

  acknowledge(userId) {
    this.status = AlertStatus.ACKNOWLEDGED;
    this.acknowledgedBy = userId;
    this.acknowledgedAt = new Date().toISOString();
    this.lastUpdated = new Date().toISOString();
  }

  resolve() {
    this.status = AlertStatus.RESOLVED;
    this.resolvedAt = new Date().toISOString();
    this.lastUpdated = new Date().toISOString();
  }

  suppress() {
    this.status = AlertStatus.SUPPRESSED;
    this.suppressionCount++;
    this.lastUpdated = new Date().toISOString();
  }

  toJSON() {
    return {
      id: this.id,
      type: this.type,
      severity: this.severity,
      title: this.title,
      message: this.message,
      details: this.details,
      status: this.status,
      timestamp: this.timestamp,
      lastUpdated: this.lastUpdated,
      acknowledgedBy: this.acknowledgedBy,
      acknowledgedAt: this.acknowledgedAt,
      resolvedAt: this.resolvedAt,
      suppressionCount: this.suppressionCount,
      correlationId: this.correlationId
    };
  }
}

/**
 * 智能告警管理器
 */
class AlertManager {
  constructor() {
    this.isRunning = false;
    this.checkInterval = null;
    this.alertHandlers = [];
    this.dependencyGraph = this.buildDependencyGraph();
  }

  /**
   * 启动告警系统
   */
  start(intervalMs = 60000) {
    if (this.isRunning) {
      logger.warn('告警系统已在运行');
      return;
    }

    this.isRunning = true;
    logger.info('启动智能告警系统', { interval: intervalMs });

    // 立即执行一次检查
    this.performAlertCheck();

    // 定期检查
    this.checkInterval = setInterval(() => {
      this.performAlertCheck();
    }, intervalMs);
  }

  /**
   * 停止告警系统
   */
  stop() {
    if (!this.isRunning) {
      return;
    }

    this.isRunning = false;
    if (this.checkInterval) {
      clearInterval(this.checkInterval);
      this.checkInterval = null;
    }

    logger.info('智能告警系统已停止');
  }

  /**
   * 执行告警检查
   */
  async performAlertCheck() {
    try {
      logger.debug('执行告警检查');

      // 1. 执行深度健康检查
      const healthCheck = await performDeepHealthCheck();

      // 2. 获取指标摘要
      const metricsSummary = getMetricsSummary();

      // 3. 分析并生成告警
      await this.analyzeSystemHealth(healthCheck);
      await this.analyzePerformanceMetrics(metricsSummary);
      await this.analyzeBusinessMetrics(metricsSummary);

      // 4. 检查告警风暴
      this.detectAlertStorm();

      // 5. 清理已解决的告警
      this.cleanupResolvedAlerts();

    } catch (error) {
      logger.error('告警检查失败:', error);
    }
  }

  /**
   * 分析系统健康状态
   */
  async analyzeSystemHealth(healthCheck) {
    // 整体健康状态告警
    if (healthCheck.status === 'critical') {
      await this.createAlert(AlertType.SYSTEM_HEALTH, AlertSeverity.CRITICAL,
        '系统健康状态严重异常',
        `系统整体健康状态为严重，评分: ${healthCheck.overallScore}`,
        {
          healthScore: healthCheck.overallScore,
          components: healthCheck.components,
          alerts: healthCheck.alerts
        });
    } else if (healthCheck.status === 'unhealthy') {
      await this.createAlert(AlertType.SYSTEM_HEALTH, AlertSeverity.WARNING,
        '系统健康状态异常',
        `系统整体健康状态不健康，评分: ${healthCheck.overallScore}`,
        {
          healthScore: healthCheck.overallScore,
          components: healthCheck.components
        });
    }

    // 组件级别告警
    for (const [componentName, component] of Object.entries(healthCheck.components)) {
      if (component.status === 'critical') {
        await this.createAlert(AlertType.SERVICE_AVAILABILITY, AlertSeverity.CRITICAL,
          `组件严重异常: ${componentName}`,
          `组件 ${componentName} 状态严重异常`,
          {
            component: componentName,
            status: component.status,
            details: component.details,
            alerts: component.alerts
          });
      } else if (component.status === 'unhealthy') {
        await this.createAlert(AlertType.SERVICE_AVAILABILITY, AlertSeverity.WARNING,
          `组件异常: ${componentName}`,
          `组件 ${componentName} 状态不健康`,
          {
            component: componentName,
            status: component.status,
            details: component.details
          });
      }
    }
  }

  /**
   * 分析性能指标
   */
  async analyzePerformanceMetrics(metricsSummary) {
    // HTTP请求响应时间告警
    const avgResponseTime = this.calculateAverageResponseTime(metricsSummary);
    if (avgResponseTime > ALERT_THRESHOLDS.responseTime.critical) {
      await this.createAlert(AlertType.PERFORMANCE, AlertSeverity.CRITICAL,
        'HTTP响应时间过长',
        `平均响应时间: ${avgResponseTime.toFixed(2)}ms`,
        {
          metric: 'http_response_time',
          value: avgResponseTime,
          threshold: ALERT_THRESHOLDS.responseTime.critical
        });
    } else if (avgResponseTime > ALERT_THRESHOLDS.responseTime.warning) {
      await this.createAlert(AlertType.PERFORMANCE, AlertSeverity.WARNING,
        'HTTP响应时间偏长',
        `平均响应时间: ${avgResponseTime.toFixed(2)}ms`,
        {
          metric: 'http_response_time',
          value: avgResponseTime,
          threshold: ALERT_THRESHOLDS.responseTime.warning
        });
    }

    // 错误率告警
    const errorRate = this.calculateErrorRate(metricsSummary);
    if (errorRate > ALERT_THRESHOLDS.errorRate.critical) {
      await this.createAlert(AlertType.PERFORMANCE, AlertSeverity.CRITICAL,
        '系统错误率过高',
        `错误率: ${(errorRate * 100).toFixed(2)}%`,
        {
          metric: 'error_rate',
          value: errorRate,
          threshold: ALERT_THRESHOLDS.errorRate.critical
        });
    } else if (errorRate > ALERT_THRESHOLDS.errorRate.warning) {
      await this.createAlert(AlertType.PERFORMANCE, AlertSeverity.WARNING,
        '系统错误率偏高',
        `错误率: ${(errorRate * 100).toFixed(2)}%`,
        {
          metric: 'error_rate',
          value: errorRate,
          threshold: ALERT_THRESHOLDS.errorRate.warning
        });
    }
  }

  /**
   * 分析业务指标
   */
  async analyzeBusinessMetrics(metricsSummary) {
    // AI推理失败率告警
    const aiInferenceMetrics = metricsSummary.ai_inference_duration_seconds;
    if (aiInferenceMetrics && aiInferenceMetrics.count > 0) {
      const aiErrorRate = this.calculateAIErrorRate(metricsSummary);
      if (aiErrorRate > ALERT_THRESHOLDS.aiInferenceFailureRate.critical) {
        await this.createAlert(AlertType.BUSINESS_METRIC, AlertSeverity.CRITICAL,
          'AI推理失败率过高',
          `AI推理失败率: ${(aiErrorRate * 100).toFixed(2)}%`,
          {
            metric: 'ai_inference_error_rate',
            value: aiErrorRate,
            threshold: ALERT_THRESHOLDS.aiInferenceFailureRate.critical
          });
      } else if (aiErrorRate > ALERT_THRESHOLDS.aiInferenceFailureRate.warning) {
        await this.createAlert(AlertType.BUSINESS_METRIC, AlertSeverity.WARNING,
          'AI推理失败率偏高',
          `AI推理失败率: ${(aiErrorRate * 100).toFixed(2)}%`,
          {
            metric: 'ai_inference_error_rate',
            value: aiErrorRate,
            threshold: ALERT_THRESHOLDS.aiInferenceFailureRate.warning
          });
      }
    }

    // 数据库连接失败率告警
    const dbErrorRate = this.calculateDatabaseErrorRate(metricsSummary);
    if (dbErrorRate > ALERT_THRESHOLDS.databaseConnectionFailureRate.critical) {
      await this.createAlert(AlertType.BUSINESS_METRIC, AlertSeverity.CRITICAL,
        '数据库连接失败率过高',
        `数据库连接失败率: ${(dbErrorRate * 100).toFixed(2)}%`,
        {
          metric: 'database_error_rate',
          value: dbErrorRate,
          threshold: ALERT_THRESHOLDS.databaseConnectionFailureRate.critical
        });
    }
  }

  /**
   * 创建告警
   */
  async createAlert(type, severity, title, message, details = {}) {
    // 检查抑制规则
    if (this.shouldSuppressAlert(type, severity, title, details)) {
      logger.debug('告警被抑制', { type, severity, title });
      return;
    }

    const alert = new Alert(type, severity, title, message, details);

    // 存储告警
    activeAlerts.set(alert.id, alert);
    alertHistory.push(alert.toJSON());

    // 限制历史记录大小
    if (alertHistory.length > 1000) {
      alertHistory.splice(0, 100);
    }

    // 记录日志
    logger.warn('新告警', {
      id: alert.id,
      type: alert.type,
      severity: alert.severity,
      title: alert.title,
      message: alert.message
    });

    // 执行告警处理器
    await this.executeAlertHandlers(alert);

    return alert;
  }

  /**
   * 检查是否应该抑制告警
   */
  shouldSuppressAlert(type, severity, title, details) {
    const now = Date.now();
    const alertKey = `${type}:${title}`;

    // 检查同类型告警抑制
    if (suppressionRules.has(alertKey)) {
      const lastAlertTime = suppressionRules.get(alertKey);
      if (now - lastAlertTime < SUPPRESSION_RULES.sameAlertSuppression) {
        return true;
      }
    }

    // 更新抑制时间
    suppressionRules.set(alertKey, now);

    // 检查依赖抑制
    if (SUPPRESSION_RULES.dependencySuppression) {
      return this.checkDependencySuppression(type, details);
    }

    return false;
  }

  /**
   * 检查依赖抑制
   */
  checkDependencySuppression(type, details) {
    // 如果是数据库相关告警，检查是否有更基础的系统告警
    if (type === AlertType.BUSINESS_METRIC && details.metric?.includes('database')) {
      const hasSystemAlert = Array.from(activeAlerts.values()).some(alert =>
        alert.type === AlertType.SYSTEM_HEALTH && alert.severity === AlertSeverity.CRITICAL
      );
      return hasSystemAlert;
    }

    return false;
  }

  /**
   * 检测告警风暴
   */
  detectAlertStorm() {
    const now = Date.now();
    const recentAlerts = alertHistory.filter(alert =>
      now - new Date(alert.timestamp).getTime() < SUPPRESSION_RULES.alertStormWindow
    );

    if (recentAlerts.length >= SUPPRESSION_RULES.alertStormThreshold) {
      this.createAlert(AlertType.SYSTEM_HEALTH, AlertSeverity.EMERGENCY,
        '检测到告警风暴',
        `${SUPPRESSION_RULES.alertStormWindow / 60000}分钟内产生了${recentAlerts.length}个告警`,
        {
          alertCount: recentAlerts.length,
          timeWindow: SUPPRESSION_RULES.alertStormWindow,
          recentAlerts: recentAlerts.slice(-10)
        });
    }
  }

  /**
   * 执行告警处理器
   */
  async executeAlertHandlers(alert) {
    for (const handler of this.alertHandlers) {
      try {
        await handler(alert);
      } catch (error) {
        logger.error('告警处理器执行失败:', error);
      }
    }
  }

  /**
   * 注册告警处理器
   */
  registerAlertHandler(handler) {
    this.alertHandlers.push(handler);
  }

  /**
   * 清理已解决的告警
   */
  cleanupResolvedAlerts() {
    const resolvedThreshold = 24 * 60 * 60 * 1000; // 24小时
    const now = Date.now();

    for (const [alertId, alert] of activeAlerts.entries()) {
      if (alert.status === AlertStatus.RESOLVED &&
          now - new Date(alert.resolvedAt).getTime() > resolvedThreshold) {
        activeAlerts.delete(alertId);
        logger.debug('清理已解决的告警', { alertId });
      }
    }
  }

  /**
   * 构建依赖图
   */
  buildDependencyGraph() {
    return {
      'database': ['ai_inference', 'scoring_tasks'],
      'ai_service': ['scoring_tasks'],
      'filesystem': ['file_upload', 'ai_inference']
    };
  }

  // 辅助计算方法
  calculateAverageResponseTime(metricsSummary) {
    const httpMetrics = metricsSummary.http_request_duration_seconds;
    if (!httpMetrics || httpMetrics.count === 0) return 0;

    return httpMetrics.sum / httpMetrics.count;
  }

  calculateErrorRate(metricsSummary) {
    const totalRequests = metricsSummary.http_requests_total?.total || 0;
    const errorRequests = metricsSummary.http_requests_errors_total?.total || 0;

    return totalRequests > 0 ? errorRequests / totalRequests : 0;
  }

  calculateAIErrorRate(metricsSummary) {
    const totalInferences = metricsSummary.ai_inference_total?.total || 0;
    const errorInferences = metricsSummary.ai_inference_errors_total?.total || 0;

    return totalInferences > 0 ? errorInferences / totalInferences : 0;
  }

  calculateDatabaseErrorRate(metricsSummary) {
    const totalQueries = metricsSummary.db_queries_total?.total || 0;
    const errorQueries = metricsSummary.db_errors_total?.total || 0;

    return totalQueries > 0 ? errorQueries / totalQueries : 0;
  }

  /**
   * 获取活跃告警
   */
  getActiveAlerts() {
    return Array.from(activeAlerts.values());
  }

  /**
   * 获取告警历史
   */
  getAlertHistory(limit = 100) {
    return alertHistory.slice(-limit);
  }

  /**
   * 确认告警
   */
  acknowledgeAlert(alertId, userId) {
    const alert = activeAlerts.get(alertId);
    if (alert) {
      alert.acknowledge(userId);
      logger.info('告警已确认', { alertId, userId });
      return true;
    }
    return false;
  }

  /**
   * 解决告警
   */
  resolveAlert(alertId) {
    const alert = activeAlerts.get(alertId);
    if (alert) {
      alert.resolve();
      logger.info('告警已解决', { alertId });
      return true;
    }
    return false;
  }
}

// 全局告警管理器实例
const alertManager = new AlertManager();

// 默认告警处理器
const defaultAlertHandler = async (alert) => {
  // 这里可以集成各种告警通知方式
  switch (alert.severity) {
    case AlertSeverity.EMERGENCY:
      // 发送紧急通知（短信、电话等）
      logger.error('🚨 紧急告警', alert.toJSON());
      break;
    case AlertSeverity.CRITICAL:
      // 发送邮件通知
      logger.error('🔴 严重告警', alert.toJSON());
      break;
    case AlertSeverity.WARNING:
      // 发送普通通知
      logger.warn('🟡 警告告警', alert.toJSON());
      break;
    default:
      logger.info('🔵 信息告警', alert.toJSON());
  }
};

// 注册默认处理器
alertManager.registerAlertHandler(defaultAlertHandler);

export {
  Alert,
  AlertManager,
  alertManager
};

export default {
  AlertSeverity,
  AlertType,
  AlertStatus,
  Alert,
  AlertManager,
  alertManager,
  start: () => alertManager.start(),
  stop: () => alertManager.stop(),
  createAlert: (type, severity, title, message, details) => alertManager.createAlert(type, severity, title, message, details),
  getActiveAlerts: () => alertManager.getActiveAlerts(),
  getAlertHistory: (limit) => alertManager.getAlertHistory(limit),
  acknowledgeAlert: (alertId, userId) => alertManager.acknowledgeAlert(alertId, userId),
  resolveAlert: (alertId) => alertManager.resolveAlert(alertId),
  registerAlertHandler: (handler) => alertManager.registerAlertHandler(handler)
};